package com.proxy.server.context;

import com.proxy.common.model.DataNode;
import com.proxy.common.model.FrontendProxy;
import com.proxy.common.utils.ExecutorUtil;
import com.proxy.router.ProxyInitialize;
import com.proxy.server.backend.BackendClient;
import com.proxy.server.backend.bio.BioBackendClient;
import com.proxy.server.backend.nio.NioBackendClient;
import com.proxy.server.frontend.session.Session;
import io.netty.channel.Channel;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * Created by liufish on 16/7/14.
 */
public class AppContext {

    private FrontendProxy frontendProxy;

    private ThreadPoolExecutor proxyExecutor;

    private List<BackendClient> clients = new ArrayList<>();

    private AppContext() {
    }

    private static class AppContextHolder {
        private static final AppContext INSTANCE = new AppContext();
    }

    public static final AppContext getInstance() {
        return AppContextHolder.INSTANCE;
    }


    public void sessionRegistered(Channel channel,Session session){
        AppDataStore.sessionMap.put(channel,session);
    }

    public void sessionUnRegistered(Channel channel){
        AppDataStore.sessionMap.remove(channel);
        channel.close();
    }

    public Session getProxySession(Channel channel){
        return AppDataStore.sessionMap.get(channel);
    }

    public void init(){

        String jsonPath = getClass().getResource("/proxy.json").getPath();

        ProxyInitialize initialize = new ProxyInitialize(jsonPath);
        frontendProxy = initialize.getFrontendProxy();
        for(DataNode node : initialize.getNodes()){
            BackendClient client = null;
            if(frontendProxy.isBio()){
                client = new BioBackendClient(node);
            }else {
                client = new NioBackendClient(node);
            }
            clients.add(client);
        }

    }

    public FrontendProxy getFrontendProxy(){
        return this.frontendProxy;
    }


    public ThreadPoolExecutor getProxyExecutor() {
        if(proxyExecutor == null){
            proxyExecutor = ExecutorUtil.create("proxy_",frontendProxy.getExecutor());
        }
        return proxyExecutor;
    }

    public List<BackendClient> getClients(){
        return this.clients;
    }


}
